﻿/*-------------------------------------------------------------------------
* 命名空间: SiliconSelect.Common/ProcessManager
* 类       名: ProcessManager
* 功      能:  进程管理类,关闭指定进程
* 时      间:  2023/9/2 19:05:10
* 版      本:  V1.0
* 作      者:  Fioman
* 格      言:  Talk is cheap,show me the code ^_^
*-------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;

namespace SiliconSelect.Common
{
    public class ProcessManager
    {
        /// <summary>
        /// 根据占用的端口号获取对应的进程Id
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public static void KillProcessByPort(List<string> addrList)
        {
            try
            {
                Process pro = new Process();

                // 设置命令行、参数
                pro.StartInfo.FileName = "cmd.exe";
                pro.StartInfo.UseShellExecute = false;
                pro.StartInfo.RedirectStandardInput = true;
                pro.StartInfo.RedirectStandardOutput = true;
                pro.StartInfo.RedirectStandardError = true;
                pro.StartInfo.CreateNoWindow = true;
                // 启动CMD
                pro.Start();
                // 运行端口检查命令
                pro.StandardInput.WriteLine("netstat -ano");
                pro.StandardInput.WriteLine("exit");

                // 获取结果
                Regex reg = new Regex(@"\s ", RegexOptions.Compiled);
                string? line = null;
                while ((line = pro.StandardOutput.ReadLine()) != null)
                {
                    line = line.Trim();
                    if (line.StartsWith("TCP", StringComparison.OrdinalIgnoreCase))
                    {
                        string[] addrPortArr = Regex.Split(line, "\\s+", RegexOptions.IgnoreCase);
                        if (addrPortArr.Length > 2)
                        {
                            string addrPort = addrPortArr[1];
                            if (addrList.Contains(addrPort))
                            {
                                if (addrPortArr[addrPortArr.Length - 1] != "0")
                                {
                                    LogHelper.WriteLog(LogType.Info, $"{addrPort}被占用的进程Id {addrPortArr[addrPortArr.Length - 1]}");
                                    KillProcess(int.Parse(addrPortArr[addrPortArr.Length - 1]));
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(LogType.Info, ExceptionHelper.GetFullException(ex, MethodBase.GetCurrentMethod()!));
            }
        }

        public static void KillProcess(int processId) //调用方法，传参
        {
            try
            {
                //    //  Process[] thisproc = Process.GetProcessesByName(processName);
                Process processWillClose = Process.GetProcessById(processId);
                LogHelper.WriteLog(LogType.Info, $"进程名称为: {processWillClose.ProcessName}");
                if (!processWillClose.CloseMainWindow() && !processWillClose.ProcessName.Contains("QtWidgetsApplication1")) //尝试关闭进程 释放资源
                {
                    processWillClose.Kill(); //强制关闭
                    LogHelper.WriteLog(LogType.Info, "关闭进程");
                }
                else
                {
                    LogHelper.WriteLog(LogType.Info, "尺寸进程,不关闭");
                }
            }
            catch //出现异常，表明 kill 进程失败
            {
                LogHelper.WriteLog(LogType.Info, $"结束进程出错");
            }
        }
    }
}
